﻿using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Globalization;
using System.Security.Policy;
using System.Web;
using Agile.Paypal.Web;


namespace Agile.Paypal
{
    /// <summary>
    /// Paypal notification
    /// </summary>


    public class PaypalNotificationItem
    {
        public decimal Amount { get; set; }
        public string Name { get; set; }
        public string Number { get; set; }

        public static PaypalNotificationItem FromRequest(HttpRequest request, int index = 0)
        {
            NameValueCollection values = request.Form;
            string i = index > 0 ? index.ToString(CultureInfo.InvariantCulture) : string.Empty;
            return new PaypalNotificationItem()
            {
                Name = values["item_name" + i],
                Amount = Utilities.Try(decimal.Parse, values["amount" + i], CultureInfo.InvariantCulture),
                Number = values["item_number" + i],
            };
        }
    }
    public class PaypalNotification
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="PaypalNotification"/> class.
        /// </summary>
        
        public PaypalNotification()
        {
          
        }

        /// <summary>
        /// Gets the transaction id.
        /// </summary>
        /// <value>The transaction id.</value>
        public string TransactionId { get; set; }

        public Decimal Gross { get; set; }

        /// <summary>
        /// Gets the type of the transaction.
        /// </summary>
        /// <value>The type of the transaction.</value>
        public string TransactionType { get; set; }
        /// <summary>
        /// Gets the subscription id.
        /// </summary>
        /// <value>The subscription id.</value>
        public string SubscriptionId { get; set; }
        /// <summary>
        /// Gets the last name.
        /// </summary>
        /// <value>The last name.</value>
        public string LastName { get; set; }
        /// <summary>
        /// Gets the residence country.
        /// </summary>
        /// <value>The residence country.</value>
        public string ResidenceCountry { get; set; }
        /// <summary>
        /// Gets the currency.
        /// </summary>
        /// <value>The currency.</value>
        public string Currency { get; set; }
        /// <summary>
        /// Gets the product.
        /// </summary>
        /// <value>The product.</value>
        public string Product { get; set; }
        /// <summary>
        /// Gets the business.
        /// </summary>
        /// <value>The business.</value>
        public string Business { get; set; }

        /// <summary>
        /// Gets a value indicating whether this <see cref="PaypalNotification"/> is recurring.
        /// </summary>
        /// <value><c>null</c> if [recurring] contains no value, <c>true</c> if [recurring]; otherwise, <c>false</c>.</value>
        public bool? Recurring { get; set; }
        /// <summary>
        /// Gets the signature.
        /// </summary>
        /// <value>The signature.</value>
        public string Signature { get; set; }
        /// <summary>
        /// Gets the payment date.
        /// </summary>
        /// <value>The payment date.</value>
        public DateTime? PaymentDate { get; set; }
        /// <summary>
        /// Gets the payer status.
        /// </summary>
        /// <value>The payer status.</value>
        public string PayerStatus { get; set; }
        /// <summary>
        /// Gets a value indicating whether [test ipn].
        /// </summary>
        /// <value><c>null</c> if [test ipn] contains no value, <c>true</c> if [test ipn]; otherwise, <c>false</c>.</value>
        public bool? TestIpn { get; set; }
        /// <summary>
        /// Gets the payer email.
        /// </summary>
        /// <value>The payer email.</value>
        public string PayerEmail { get; set; }
        /// <summary>
        /// Gets the first name.
        /// </summary>
        /// <value>The first name.</value>
        public string FirstName { get; set; }
        /// <summary>
        /// Gets the receiver email.
        /// </summary>
        /// <value>The receiver email.</value>
        public string ReceiverEmail { get; set; }
        /// <summary>
        /// Gets the payer id.
        /// </summary>
        /// <value>The payer id.</value>
        public string PayerId { get; set; }
        /// <summary>
        /// Gets the recurrencies.
        /// </summary>
        /// <value>The recurrencies.</value>
        public int? Recurrencies { get; set; }
        /// <summary>
        /// Gets the subscription date.
        /// </summary>
        /// <value>The subscription date.</value>
        public DateTime? SubscriptionDate { get; set; }
        /// <summary>
        /// Gets the charset.
        /// </summary>
        /// <value>The charset.</value>
        public string Charset { get; set; }
        /// <summary>
        /// Gets the notify version.
        /// </summary>
        /// <value>The notify version.</value>
        public string NotifyVersion { get; set; }
        /// <summary>
        /// Gets the frequency quantity.
        /// </summary>
        /// <value>The frequency quantity.</value>
        public int? FrequencyQuantity { get; set; }
        /// <summary>
        /// Gets the frequency unit of time.
        /// </summary>
        /// <value>The frequency unit of time.</value>
        public char? Frequency { get; set; }
        /// <summary>
        /// Gets the ipn track id.
        /// </summary>
        /// <value>The ipn track id.</value>
        public string IpnTrackId { get; set; }
        /// <summary>
        /// Gets the custom data.
        /// </summary>
        /// <value>The custom data.</value>
        public string CustomData { get; set; }
        /// <summary>
        /// Gets the transaction subject.
        /// </summary>
        /// <value>The transaction subject.</value>
        public string TransactionSubject { get; set; }

        public decimal TransactionFee { get; set; }

        public PaypalNotificationItem[] Items { get; protected set; }

        
        public static PaypalNotification FromRequest(HttpRequest request)
        {

            NameValueCollection values = request.Form;
   
            List<PaypalNotificationItem> items = new List<PaypalNotificationItem>();
            if (!string.IsNullOrWhiteSpace(values["item_name"]))
                items.Add(PaypalNotificationItem.FromRequest(request));

            for (int i = 1; !string.IsNullOrWhiteSpace(values["item_name" + i]); i++)
                items.Add(PaypalNotificationItem.FromRequest(request, i));

            return new PaypalNotification()
            {
                TransactionFee = Utilities.Try(() => decimal.Parse(values["mc_fee"],CultureInfo.InvariantCulture)),
                Gross = Utilities.Try(() => decimal.Parse(values["mc_gross"], CultureInfo.InvariantCulture)),
                TransactionType = values["txn_type"],
                SubscriptionId = values["subscr_id"],
                LastName = values["last_name"],
                ResidenceCountry = values["residence_country"],
                Currency = values["mc_currency"],
                Items = items.ToArray(),
                Business = values["business"],
                Recurring = values["recurring"] == "1",
                PayerStatus = values["payer_status"],
                PayerEmail = values["payer_email"],
                FirstName = values["first_name"],
                ReceiverEmail = values["receiver_email"],
                PayerId = values["payer_id"],
                TransactionId = values["txn_id"],
                Charset = values["charset"],
                NotifyVersion = values["notify_version"],
                TestIpn = values["test_ipn"] == "1",
                TransactionSubject = values["transaction_subject"],
                CustomData = values["custom"],
                IpnTrackId = values["ipn_track_id"],
                Recurrencies = Utilities.Try(int.Parse, values["recur_times"]),
                SubscriptionDate = Utilities.Try(DateTime.Parse, values["subscr_date"]),
                PaymentDate = Utilities.Try(() => DateTime.ParseExact(values["payment_date"], "HH:mm:ss MMM dd, yyyy PDT", CultureInfo.InvariantCulture, DateTimeStyles.None)),
                Signature = values["verify_sign"],
                PaymentStatus = values["payment_status"],
            };
        }

        public string PaymentStatus { get; set; }
    }
}